Option Explicit

Private Const TEST_TABLE_NAME As String = "table1"
Private Const TEST_POINT As String = "."
Private Const TEST_COL_NAME As String = "col1"
Private Const TEST_SHARE_LINE_COMMENT As String = "--aaaaaa"
Private Const TEST_SINGLE_LINE_COMMENT As String = "--bbbbb"

' ======================================================================
' 执行所有测试用例
' ======================================================================
Public Sub test_all_case()
    ' ==================================================
    ' Public 方法测试
    ' ==================================================
    ' 测试: setNeedMultiLineWhenHasComma 方法
    test_ThisClass_setNeedMultiLineWhenHasComma

    ' ==================================================
    ' ISqlFormatterElem 接口实现测试
    ' ==================================================
    ' 测试: addComponent 方法
    test_ISqlFormatterElem_addComponent
    ' 测试: addComponentToFirst 方法
    test_ISqlFormatterElem_addComponentToFirst
    ' 测试: canAddComponentToFirst 方法
    test_ISqlFormatterElem_canAddComponentToFirst
    ' 测试: getAlignmentElemGroups 方法
    test_ISqlFormatterElem_getAlignmentElemGroups
    ' 测试: setElemNestCount 方法
    test_ISqlFormatterElem_setElemNestCount
    ' 测试: setPrefixSpaceCount 方法
    test_ISqlFormatterElem_setPrefixSpaceCount
    ' 测试: hasBoundaryParenthesis 方法
    test_ISqlFormatterElem_hasBoundaryParenthesis
    ' 测试: addBoundaryLeftParenthesis 方法
    test_ISqlFormatterElem_addBoundaryLeftParenthesis
    ' 测试: addBoundaryRightParenthesis 方法
    test_ISqlFormatterElem_addBoundaryRightParenthesis
    ' 测试: getType 方法
    test_ISqlFormatterElem_getType
    ' 测试: isComment 方法
    test_ISqlFormatterElem_isComment
    ' 测试: isShareLineComment 方法
    test_ISqlFormatterElem_isShareLineComment
    ' 测试: isSingleLineComment 方法
    test_ISqlFormatterElem_isSingleLineComment
    ' 测试: isEndsWithComment 方法
    test_ISqlFormatterElem_isEndsWithComment
    ' 测试: isMultiLine 方法
    test_ISqlFormatterElem_isMultiLine
    ' 测试: toString + toStringArray 方法
    test_ISqlFormatterElem_toString_toStringArray
End Sub


' ======================================================================
' 测试通用处理
' ======================================================================

' 获取一个任意名称的 STR_NAME token
Private Function getStrNameToken(ByRef s As String) As SqlToken
    Set getStrNameToken = New SqlToken
    getStrNameToken.Init s, SqlTokenType.STR_NAME
End Function

' 获取表名 token
Private Function getTableNameToken() As SqlToken
    Set getTableNameToken = New SqlToken
    getTableNameToken.Init TEST_TABLE_NAME, SqlTokenType.STR_NAME
End Function

' 获取 [.] token
Private Function getPointToken() As SqlToken
    Set getPointToken = New SqlToken
    getPointToken.Init TEST_POINT, SqlTokenType.POINT
End Function

' 获取列名 token
Private Function getColNameToken() As SqlToken
    Set getColNameToken = New SqlToken
    getColNameToken.Init TEST_COL_NAME, SqlTokenType.STR_NAME
End Function

' 获取和前一个元素在同一行的注释
Private Function getShareLineCommentToken() As SqlToken
    Set getShareLineCommentToken = New SqlToken
    getShareLineCommentToken.Init TEST_SHARE_LINE_COMMENT, SqlTokenType.SHARE_LINE_COMMENT
End Function

' 获取一个单行的注释
Private Function getSingleLineCommentToken() As SqlToken
    Set getSingleLineCommentToken = New SqlToken
    getSingleLineCommentToken.Init TEST_SINGLE_LINE_COMMENT, SqlTokenType.SINGLE_LINE_COMMENT
End Function

' 获取一个逗号的元素
Private Function getCommaToken() As SqlToken
    Set getCommaToken = New SqlToken
    getCommaToken.Init ",", SqlTokenType.COMMA
End Function

' 获取一个多行的元素
' 多行连接的结果:
' "("
' "    " & TEST_TABLE_NAME & ","
' "    " & TEST_TABLE_NAME
' ")"
Private Function getMultiLineElem() As ISqlFormatterElem
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    ' ==============================
    ' 2. 单行变多行的测试
    ' ==============================
    ' 1. 增加一个单行元素
    elem.addComponent getTableNameToken

    ' 2. 手动设置为多行元素，仍然是单行
    g.setNeedMultiLineWhenHasComma True

    ' 3. 在末尾添加一个逗号元素，仍然是单行的
    elem.addComponent getCommaToken

    ' 4. 设置边界括号后，仍然是单行的
    elem.addBoundaryLeftParenthesis
    elem.addBoundaryRightParenthesis

    ' 5. 再增加一个单行元素，变成多行的
    elem.addComponent getTableNameToken

    Set getMultiLineElem = elem
End Function

' ======================================================================
' Public 方法测试
' ======================================================================
' 测试: setNeedMultiLineWhenHasComma 方法
Private Sub test_ThisClass_setNeedMultiLineWhenHasComma()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    ' ==============================
    ' 2. 单行变多行的测试
    ' ==============================
    ' 1. 增加一个单行元素
    elem.addComponent getTableNameToken
    Debug.Assert elem.isMultiLine = False

    ' 2. 手动设置为多行元素，仍然是单行
    g.setNeedMultiLineWhenHasComma True
    Debug.Assert elem.isMultiLine = False

    ' 3. 在末尾添加一个逗号元素，仍然是单行的
    elem.addComponent getCommaToken
    Debug.Assert elem.isMultiLine = False

    ' 4. 设置边界括号后，仍然是单行的
    elem.addBoundaryLeftParenthesis
    Debug.Assert elem.isMultiLine = False
    elem.addBoundaryRightParenthesis
    Debug.Assert elem.isMultiLine = False

    ' 5. 再增加一个单行元素，变成多行的
    elem.addComponent getTableNameToken
    Debug.Assert elem.isMultiLine = True

    ' ==============================
    ' 3. 多行时的测试
    ' ==============================
    ' elem 现在已经是多行的了，则继续使用。以 elem2 为核心做这一步的测试

    Dim g2 As SqlFormatterCommaDeliMultiElem
    Set g2 = New SqlFormatterCommaDeliMultiElem

    Dim elem2 As ISqlFormatterElem
    Set elem2 = g2

    ' 1. 保存一个多行元素后，是多行的
    elem2.addComponent elem
    Debug.Assert elem2.isMultiLine = True

    ' 2. 在末尾添加一个逗号元素，仍然是多行的
    elem2.addComponent getCommaToken
    Debug.Assert elem2.isMultiLine = True

    ' 3. 再增加一个单行元素，仍然是多行的
    elem2.addComponent getTableNameToken
    Debug.Assert elem2.isMultiLine = True

    ' ==============================
    ' 4. 元素以注释结尾，并且包含边界括号，是多行的
    ' ==============================
    Set g2 = New SqlFormatterCommaDeliMultiElem
    Set elem2 = g2

    ' 增加一个元素
    elem2.addComponent getTableNameToken
    Debug.Assert elem2.isMultiLine = False

    ' 增加一个和前一个元素同行的注释
    elem2.addComponent getShareLineCommentToken
    Debug.Assert elem2.isMultiLine = False

    ' 增加边界括号，变为多行的
    elem2.addBoundaryLeftParenthesis
    Debug.Assert elem2.isMultiLine = True
    elem2.addBoundaryRightParenthesis
    Debug.Assert elem2.isMultiLine = True

    ' ==============================
    ' 5. 单行并在左侧添加逗号，变成多行
    ' ==============================
    Set g2 = New SqlFormatterCommaDeliMultiElem
    Set elem2 = g2

    ' 1. 增加一个单行元素
    elem2.addComponent getTableNameToken
    Debug.Assert elem2.isMultiLine = False

    ' 2. 手动设置为多行元素，仍然是单行
    g2.setNeedMultiLineWhenHasComma True
    Debug.Assert elem2.isMultiLine = False

    ' 3. 在左侧添加一个逗号元素，变成多行的
    elem2.addComponentToFirst getCommaToken
    Debug.Assert elem2.isMultiLine = True

    ' ==============================
    ' 6. 不做设置: 添加一个单行元素，增加一个单行注释
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem
    Set elem = g

    ' 只有单行注释时，是单行
    elem.addComponent getSingleLineCommentToken
    Debug.Assert elem.isMultiLine = False
    ' 单行注释 + 单行元素时，是多行
    elem.addComponent getTableNameToken
    Debug.Assert elem.isMultiLine = True

End Sub

' ======================================================================
' ISqlFormatterElem 接口实现测试
' ======================================================================
' 测试: addComponent 方法
Private Sub test_ISqlFormatterElem_addComponent()
    Dim config As SqlFormatterConfiguration
    Set config = New SqlFormatterConfiguration

    Dim strArr As IPrimitiveArrayRef

    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    ' ==============================
    ' 2. 单行变多行的测试
    ' ==============================
    ' 1. 增加一个单行元素
    elem.addComponent getTableNameToken

    ' 2. 手动设置为多行元素，仍然是单行
    g.setNeedMultiLineWhenHasComma True

    ' 3. 在末尾添加一个逗号元素，仍然是单行的
    elem.addComponent getCommaToken

    ' 4. 设置边界括号后，仍然是单行的
    elem.addBoundaryLeftParenthesis
    elem.addBoundaryRightParenthesis

    ' 5. 再增加一个单行元素，变成多行的
    elem.addComponent getTableNameToken

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 4
    Debug.Assert strArr.Item(0) = "("
    Debug.Assert strArr.Item(1) = "    " & TEST_TABLE_NAME & ","
    Debug.Assert strArr.Item(2) = "    " & TEST_TABLE_NAME
    Debug.Assert strArr.Item(3) = ")"

    ' ==============================
    ' 3. 多行时的测试
    ' ==============================
    ' elem 现在已经是多行的了，则继续使用。以 elem2 为核心做这一步的测试

    Dim g2 As SqlFormatterCommaDeliMultiElem
    Set g2 = New SqlFormatterCommaDeliMultiElem

    Dim elem2 As ISqlFormatterElem
    Set elem2 = g2

    ' 1. 保存一个多行元素后，是多行的
    elem2.addComponent elem

    ' 2. 在末尾添加一个逗号元素，仍然是多行的
    elem2.addComponent getCommaToken

    ' 3. 再增加一个单行元素，仍然是多行的
    elem2.addComponent getTableNameToken

    Set strArr = elem2.toStringArray(config)
    Debug.Assert strArr.Count = 5
    Debug.Assert strArr.Item(0) = "("
    Debug.Assert strArr.Item(1) = "    " & TEST_TABLE_NAME & ","
    Debug.Assert strArr.Item(2) = "    " & TEST_TABLE_NAME
    Debug.Assert strArr.Item(3) = "),"
    Debug.Assert strArr.Item(4) = TEST_TABLE_NAME

    ' ==============================
    ' 4. 元素以注释结尾，并且包含边界括号，是多行的
    ' ==============================
    Set g2 = New SqlFormatterCommaDeliMultiElem
    Set elem2 = g2

    ' 增加一个元素
    elem2.addComponent getTableNameToken

    ' 增加一个和前一个元素同行的注释
    elem2.addComponent getShareLineCommentToken

    Set strArr = elem2.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME & " " & TEST_SHARE_LINE_COMMENT

    ' 增加边界括号，变为多行的
    elem2.addBoundaryLeftParenthesis
    elem2.addBoundaryRightParenthesis

    Set strArr = elem2.toStringArray(config)
    Debug.Assert strArr.Count = 3
    Debug.Assert strArr.Item(0) = "("
    Debug.Assert strArr.Item(1) = "    " & TEST_TABLE_NAME & " " & TEST_SHARE_LINE_COMMENT
    Debug.Assert strArr.Item(2) = ")"

    ' ==============================
    ' 5. 不做设置: 添加一个单行元素，增加一个单行注释
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem
    Set elem = g

    elem.addComponent getTableNameToken
    elem.addComponent getSingleLineCommentToken
    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 2
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME
    Debug.Assert strArr.Item(1) = TEST_SINGLE_LINE_COMMENT

    ' ==============================
    ' 6. 测试: 单行元素 + 逗号 + 同行注释 + 设置为多行
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem
    g.setNeedMultiLineWhenHasComma True
    Set elem = g

    ' 1. 增加一个单行元素
    elem.addComponent getStrNameToken("x1")
    ' 2. 添加一个逗号元素
    elem.addComponent getCommaToken
    ' 3. 添加一个同行注释
    elem.addComponent getShareLineCommentToken

    ' 检查是单行的
    Debug.Assert g.ISqlFormatterElem_isMultiLine = False
    ' 检查: 是注释结尾
    Debug.Assert g.ISqlFormatterElem_isEndsWithComment = True

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = "x1, " & TEST_SHARE_LINE_COMMENT

    ' 4. 增加左边界括号
    g.ISqlFormatterElem_addBoundaryLeftParenthesis

    ' 检查是多行的
    Debug.Assert g.ISqlFormatterElem_isMultiLine = True
    ' 检查: 是注释结尾
    Debug.Assert g.ISqlFormatterElem_isEndsWithComment = True

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 2
    Debug.Assert strArr.Item(0) = "("
    Debug.Assert strArr.Item(1) = "    x1, " & TEST_SHARE_LINE_COMMENT

    ' ==============================
    ' 7. 测试: 单行元素 + 逗号 + 同行注释 + 第二个单行注释 + 设置为多行
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem
    g.setNeedMultiLineWhenHasComma True
    Set elem = g

    ' 1. 增加一个单行元素
    elem.addComponent getStrNameToken("x1")
    ' 2. 添加一个逗号元素
    elem.addComponent getCommaToken
    ' 3. 添加一个同行注释
    elem.addComponent getShareLineCommentToken
    ' 4. 增加第二个单行元素
    elem.addComponent getStrNameToken("x2")

    ' 检查是多行的
    Debug.Assert g.ISqlFormatterElem_isMultiLine = True
    ' 检查: 不是注释结尾
    Debug.Assert g.ISqlFormatterElem_isEndsWithComment = False

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 2
    Debug.Assert strArr.Item(0) = "x1, " & TEST_SHARE_LINE_COMMENT
    Debug.Assert strArr.Item(1) = "x2"

End Sub

' 测试: addComponentToFirst 方法
Private Sub test_ISqlFormatterElem_addComponentToFirst()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    Dim config As SqlFormatterConfiguration
    Set config = New SqlFormatterConfiguration

    Dim strArr As IPrimitiveArrayRef

    ' ==============================
    ' 2. 测试: 单行
    ' ==============================
    ' 1. 增加一个单行元素
    elem.addComponent getTableNameToken

    ' 3. 在左侧添加一个逗号元素
    elem.addComponentToFirst getCommaToken

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = ", " & TEST_TABLE_NAME

    ' ==============================
    ' 3. 测试: 附加边界括号
    ' ==============================
    elem.addBoundaryLeftParenthesis
    elem.addBoundaryRightParenthesis

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = "(, " & TEST_TABLE_NAME & ")"

    ' ==============================
    ' 4. 测试: 将单行设置为多行
    ' ==============================
    g.setNeedMultiLineWhenHasComma True
    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 4
    Debug.Assert strArr.Item(0) = "("
    Debug.Assert strArr.Item(1) = "    ,"
    Debug.Assert strArr.Item(2) = "    " & TEST_TABLE_NAME
    Debug.Assert strArr.Item(3) = ")"

    ' ==============================
    ' 5. 不做设置: 添加增加一个单行注释，一个单行元素
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem
    Set elem = g

    elem.addComponent getTableNameToken
    elem.addComponentToFirst getSingleLineCommentToken
    ' 是多行的
    Debug.Assert elem.isMultiLine = True

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 2
    Debug.Assert strArr.Item(0) = TEST_SINGLE_LINE_COMMENT
    Debug.Assert strArr.Item(1) = TEST_TABLE_NAME

    ' ==============================
    ' 6. 只从左侧增加一个单行注释仍然是单行的
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem
    Set elem = g

    ' 从左侧增加一个单行注释
    elem.addComponentToFirst getSingleLineCommentToken
    ' 是单行的
    Debug.Assert elem.isMultiLine = False

    ' 从左侧增加一个单行元素
    elem.addComponentToFirst getTableNameToken
    ' 是多行的
    Debug.Assert elem.isMultiLine = True

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 2
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME
    Debug.Assert strArr.Item(1) = TEST_SINGLE_LINE_COMMENT
End Sub

' 测试: canAddComponentToFirst 方法
Private Sub test_ISqlFormatterElem_canAddComponentToFirst()
    Dim g As SqlFormatterCommaDeliMultiElem

    ' ==============================
    ' 1. 只增加一个单行元素: True
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem
    g.ISqlFormatterElem_addComponent getTableNameToken
    Debug.Assert g.ISqlFormatterElem_canAddComponentToFirst = True

    ' ==============================
    ' 2. 只增加左边界括号: False
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem
    g.ISqlFormatterElem_addBoundaryLeftParenthesis
    Debug.Assert g.ISqlFormatterElem_canAddComponentToFirst = False

    ' ==============================
    ' 3. 只增加右边界括号: True
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem
    g.ISqlFormatterElem_addBoundaryRightParenthesis
    Debug.Assert g.ISqlFormatterElem_canAddComponentToFirst = True

    ' ==============================
    ' 4. 添加左右边界括号: True
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem
    g.ISqlFormatterElem_addBoundaryLeftParenthesis
    g.ISqlFormatterElem_addBoundaryRightParenthesis
    Debug.Assert g.ISqlFormatterElem_canAddComponentToFirst = False
End Sub

' 测试: getAlignmentElemGroups 方法
Private Sub test_ISqlFormatterElem_getAlignmentElemGroups()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem
    Dim condition As SqlFormatterTwoElemCondition
    Dim condition2 As SqlFormatterTwoElemCondition

    Dim elem As ISqlFormatterElem
    Set elem = g

    Dim groups As IObjArrayRef
    Dim group As IObjArrayRef

    ' ==============================
    ' 2. 在添加元素之前进行检查
    ' ==============================
    Debug.Assert elem.getAlignmentElemGroups Is Nothing

    ' ==============================
    ' 3. 添加第一个单行元素后再检查
    ' ==============================
    elem.addComponent getTableNameToken
    Debug.Assert elem.getAlignmentElemGroups Is Nothing

    ' ==============================
    ' 4. 添加第一个条件对象
    ' ==============================
    Set condition = New SqlFormatterTwoElemCondition
    elem.addComponent condition

    Set groups = elem.getAlignmentElemGroups
    Debug.Assert groups.Count = 1
    Set group = groups.Item(0)
    Debug.Assert group.Count = 1
    Debug.Assert group.Item(0) Is condition

    ' ==============================
    ' 5. 添加第二个条件对象
    ' ==============================
    Set condition2 = New SqlFormatterTwoElemCondition
    elem.addComponent condition2

    Set groups = elem.getAlignmentElemGroups
    Debug.Assert groups.Count = 2
    ' 检查第一个条件
    Set group = groups.Item(0)
    Debug.Assert group.Count = 1
    Debug.Assert group.Item(0) Is condition
    ' 检查第二个条件
    Set group = groups.Item(1)
    Debug.Assert group.Count = 1
    Debug.Assert group.Item(0) Is condition2

    ' ==============================
    ' 6. 添加一个包含多个条件对象的组合对象
    ' ==============================
    ' 创建一个包含多个条件的组合对象
    Dim multiConditions As SqlFormatterCommaDeliMultiElem
    Set multiConditions = New SqlFormatterCommaDeliMultiElem
    Dim condition3 As SqlFormatterTwoElemCondition
    Set condition3 = New SqlFormatterTwoElemCondition
    Dim condition4 As SqlFormatterTwoElemCondition
    Set condition4 = New SqlFormatterTwoElemCondition
    multiConditions.ISqlFormatterElem_addComponent condition3
    multiConditions.ISqlFormatterElem_addComponent condition4

    ' 将这个组合对象保存到 elem
    elem.addComponent multiConditions

    Set groups = elem.getAlignmentElemGroups
    Debug.Assert groups.Count = 4
    ' 检查第一个条件
    Set group = groups.Item(0)
    Debug.Assert group.Count = 1
    Debug.Assert group.Item(0) Is condition
    ' 检查第二个条件
    Set group = groups.Item(1)
    Debug.Assert group.Count = 1
    Debug.Assert group.Item(0) Is condition2
    ' 检查第三个条件
    Set group = groups.Item(2)
    Debug.Assert group.Count = 1
    Debug.Assert group.Item(0) Is condition3
    ' 检查第四个条件
    Set group = groups.Item(3)
    Debug.Assert group.Count = 1
    Debug.Assert group.Item(0) Is condition4

End Sub

' 测试: setElemNestCount 方法
Private Sub test_ISqlFormatterElem_setElemNestCount()
    ' 无法测试
End Sub

' 测试: setPrefixSpaceCount 方法
Private Sub test_ISqlFormatterElem_setPrefixSpaceCount()
    ' 无法测试
End Sub

' 测试: hasBoundaryParenthesis 方法
Private Sub test_ISqlFormatterElem_hasBoundaryParenthesis()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    ' ==============================
    ' 2. 测试
    ' ==============================
    ' 2. 增加左边界括号
    elem.addBoundaryLeftParenthesis
    Debug.Assert elem.hasBoundaryParenthesis = True

    ' 3. 增加右边界括号
    elem.addBoundaryRightParenthesis
    Debug.Assert elem.hasBoundaryParenthesis = True

    ' 4. 重新创建对象，并只添加右边界括号
    Set g = New SqlFormatterCommaDeliMultiElem
    Set elem = g

    elem.addComponent getTableNameToken
    Debug.Assert elem.hasBoundaryParenthesis = False

    '    增加右边界括号
    elem.addBoundaryRightParenthesis
    Debug.Assert elem.hasBoundaryParenthesis = True
End Sub

' 测试: addBoundaryLeftParenthesis 方法
Private Sub test_ISqlFormatterElem_addBoundaryLeftParenthesis()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    Dim config As SqlFormatterConfiguration
    Set config = New SqlFormatterConfiguration

    Dim strArr As IPrimitiveArrayRef

    ' ==============================
    ' 2. 添加一个元素
    ' ==============================
    elem.addComponent getTableNameToken
    Debug.Assert elem.toString(config) = TEST_TABLE_NAME

    ' ==============================
    ' 3. 添加一个左括号
    ' ==============================
    elem.addBoundaryLeftParenthesis
    Debug.Assert elem.toString(config) = "(" & TEST_TABLE_NAME

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = "(" & TEST_TABLE_NAME

    ' ==============================
    ' 4. 添加多个左括号
    ' ==============================
    elem.addBoundaryLeftParenthesis(3)
    Debug.Assert elem.toString(config) = "((((" & TEST_TABLE_NAME

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = "((((" & TEST_TABLE_NAME
End Sub

' 测试: addBoundaryRightParenthesis 方法
Private Sub test_ISqlFormatterElem_addBoundaryRightParenthesis()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    Dim config As SqlFormatterConfiguration
    Set config = New SqlFormatterConfiguration

    Dim strArr As IPrimitiveArrayRef

    ' ==============================
    ' 2. 添加一个元素
    ' ==============================
    elem.addComponent getTableNameToken
    Debug.Assert elem.toString(config) = TEST_TABLE_NAME

    ' ==============================
    ' 3. 添加一个右括号
    ' ==============================
    elem.addBoundaryRightParenthesis
    Debug.Assert elem.toString(config) = TEST_TABLE_NAME & ")"

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME & ")"

    ' ==============================
    ' 4. 添加多个右括号
    ' ==============================
    elem.addBoundaryRightParenthesis(3)
    Debug.Assert elem.toString(config) = TEST_TABLE_NAME & "))))"

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME & "))))"
End Sub

' 测试: getType 方法
Private Sub test_ISqlFormatterElem_getType()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    Dim config As SqlFormatterConfiguration
    Set config = New SqlFormatterConfiguration

    Dim strArr As IPrimitiveArrayRef

    ' ==============================
    ' 2. 默认没有类型
    ' ==============================
    Debug.Assert elem.getType = SqlTokenType.NO_MEAN

    ' ==============================
    ' 3. 添加一个元素后，也没有类型
    ' ==============================
    elem.addComponent getTableNameToken
    Debug.Assert elem.getType = SqlTokenType.NO_MEAN
End Sub

' 测试: isComment 方法
Private Sub test_ISqlFormatterElem_isComment()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g
    ' ==============================
    ' 2. 默认为 false
    ' ==============================
    Debug.Assert elem.isComment = False

    ' ==============================
    ' 3. 即使添加一个注释，也是 false
    ' ==============================
    elem.addComponent getShareLineCommentToken
    Debug.Assert elem.isComment = False

    elem.addComponent getSingleLineCommentToken
    Debug.Assert elem.isComment = False
End Sub

' 测试: isShareLineComment 方法
Private Sub test_ISqlFormatterElem_isShareLineComment()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    ' ==============================
    ' 2. 默认为 false
    ' ==============================
    Debug.Assert elem.isShareLineComment = False

    ' ==============================
    ' 3. 即使添加一个注释，也是 false
    ' ==============================
    elem.addComponent getShareLineCommentToken
    Debug.Assert elem.isShareLineComment = False

    elem.addComponent getSingleLineCommentToken
    Debug.Assert elem.isShareLineComment = False
End Sub

' 测试: isSingleLineComment 方法
Private Sub test_ISqlFormatterElem_isSingleLineComment()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    ' ==============================
    ' 2. 默认为 false
    ' ==============================
    Debug.Assert elem.isShareLineComment = False

    ' ==============================
    ' 3. 即使添加一个注释，也是 false
    ' ==============================
    elem.addComponent getShareLineCommentToken
    Debug.Assert elem.isSingleLineComment = False

    elem.addComponent getSingleLineCommentToken
    Debug.Assert elem.isSingleLineComment = False
End Sub

' 测试: isEndsWithComment 方法
Private Sub test_ISqlFormatterElem_isEndsWithComment()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    ' ==============================
    ' 2. 默认为 false
    ' ==============================
    Debug.Assert elem.isEndsWithComment = False

    ' ==============================
    ' 3. 测试
    ' ==============================
    ' 1. 添加一个元素
    elem.addComponent getTableNameToken
    Debug.Assert elem.isEndsWithComment = False

    ' 2. 添加一个和前一个元素同一行的注释
    elem.addComponent getShareLineCommentToken
    Debug.Assert elem.isEndsWithComment = True

    ' 3. 再添加一个非注释元素
    elem.addComponent getTableNameToken
    Debug.Assert elem.isEndsWithComment = False

    ' 4. 添加一个单行注释
    elem.addComponent getSingleLineCommentToken
    Debug.Assert elem.isEndsWithComment = True

    ' 5. 添加左括号 --> 仍然是以注释结尾的
    elem.addBoundaryLeftParenthesis
    Debug.Assert elem.isEndsWithComment = True

    ' 6. 添加右括号 --> 不是以注释结尾的
    elem.addBoundaryRightParenthesis
    Debug.Assert elem.isEndsWithComment = False
End Sub

' 测试: isMultiLine 方法
Private Sub test_ISqlFormatterElem_isMultiLine()
    ' 参考: test_ThisClass_setNeedMultiLineWhenHasComma
End Sub

' 测试: toString + toStringArray 方法
Private Sub test_ISqlFormatterElem_toString_toStringArray()
    ' ==============================
    ' 1. 初始化
    ' ==============================
    Dim g As SqlFormatterCommaDeliMultiElem
    Set g = New SqlFormatterCommaDeliMultiElem

    Dim elem As ISqlFormatterElem
    Set elem = g

    Dim config As SqlFormatterConfiguration
    Set config = New SqlFormatterConfiguration

    Dim strArr As IPrimitiveArrayRef

    ' ==============================
    ' 2. 添加第一个单行元素
    ' ==============================
    elem.addComponent getTableNameToken
    Debug.Assert elem.toString(config) = TEST_TABLE_NAME

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME

    ' ==============================
    ' 3. 添加第二个单行元素
    ' ==============================
    elem.addComponent getColNameToken
    Debug.Assert elem.toString(config) = TEST_TABLE_NAME & " " & TEST_COL_NAME

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME & " " & TEST_COL_NAME

    ' ==============================
    ' 4. 添加一个逗号
    ' ==============================
    elem.addComponent getCommaToken
    Debug.Assert elem.toString(config) = TEST_TABLE_NAME & " " & TEST_COL_NAME & ","

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME & " " & TEST_COL_NAME & ","

    ' ==============================
    ' 5. 添加第三个单行元素
    ' ==============================
    elem.addComponent getColNameToken
    Debug.Assert elem.toString(config) = TEST_TABLE_NAME & " " & TEST_COL_NAME & ", " & TEST_COL_NAME

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME & " " & TEST_COL_NAME & ", " & TEST_COL_NAME

    ' ==============================
    ' 6. 单行情况下，设置为遇到逗号要换行
    ' ==============================
    g.setNeedMultiLineWhenHasComma True
    Debug.Assert elem.toString(config) = TEST_TABLE_NAME & " " & TEST_COL_NAME & "," & vbCrLf & _
                                         TEST_COL_NAME

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 2
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME & " " & TEST_COL_NAME & ","
    Debug.Assert strArr.Item(1) = TEST_COL_NAME

    ' ==============================
    ' 5. 添加边界括号
    ' ==============================
    elem.addBoundaryLeftParenthesis(2)
    elem.addBoundaryRightParenthesis(2)

    g.setNeedMultiLineWhenHasComma True
    Debug.Assert elem.toString(config) = "((" & vbCrLf & _
                                         "    " & TEST_TABLE_NAME & " " & TEST_COL_NAME & "," & vbCrLf & _
                                         "    " & TEST_COL_NAME & vbCrLf & _
                                         "))"

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 4
    Debug.Assert strArr.Item(0) = "(("
    Debug.Assert strArr.Item(1) = "    " & TEST_TABLE_NAME & " " & TEST_COL_NAME & ","
    Debug.Assert strArr.Item(2) = "    " & TEST_COL_NAME
    Debug.Assert strArr.Item(3) = "))"

    ' ==============================
    ' 6. 重新设置为单行元素后，再次检查括号
    ' ==============================
    g.setNeedMultiLineWhenHasComma False
    Debug.Assert elem.toString(config) = "((" & TEST_TABLE_NAME & " " & TEST_COL_NAME & ", " & TEST_COL_NAME & "))"

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 1
    Debug.Assert strArr.Item(0) = "((" & TEST_TABLE_NAME & " " & TEST_COL_NAME & ", " & TEST_COL_NAME & "))"

    ' ==============================
    ' 7. 添加一个多行的元素，默认变为多行的 (这里的 needMultiLineWhenHasComma 已经是 False 了)
    ' ==============================
    elem.addComponent getCommaToken
    elem.addComponent getMultiLineElem

    ' 将边界括号去掉
    elem.addBoundaryLeftParenthesis(-2)
    elem.addBoundaryRightParenthesis(-2)

    Debug.Assert elem.toString(config) = TEST_TABLE_NAME & " " & TEST_COL_NAME & "," & vbCrLf & _
                                         TEST_COL_NAME & "," & vbCrLf & _
                                         "(" & vbCrLf & _
                                         "    " & TEST_TABLE_NAME & "," & vbCrLf & _
                                         "    " & TEST_TABLE_NAME & vbCrLf & _
                                         ")"

    Set strArr = elem.toStringArray(config)
    Debug.Assert strArr.Count = 6
    Debug.Assert strArr.Item(0) = TEST_TABLE_NAME & " " & TEST_COL_NAME & ","
    Debug.Assert strArr.Item(1) = TEST_COL_NAME & ","
    Debug.Assert strArr.Item(2) = "("
    Debug.Assert strArr.Item(3) = "    " & TEST_TABLE_NAME & ","
    Debug.Assert strArr.Item(4) = "    " & TEST_TABLE_NAME
    Debug.Assert strArr.Item(5) = ")"

    ' ==============================
    ' 8. 特殊case: 左括号 + 一个同行注释 + 一个元素
    ' ==============================
    Set g = New SqlFormatterCommaDeliMultiElem

    ' 1. 添加一个和前一个元素同一行的注释
    g.ISqlFormatterElem_addComponent getShareLineCommentToken
    ' 2. 添加多个单行元素
    g.ISqlFormatterElem_addComponent getStrNameToken("x1")
    ' 3. 设置边界括号: 左边界括号
    g.ISqlFormatterElem_addBoundaryLeftParenthesis

    Set strArr = g.ISqlFormatterElem_toStringArray(config)
    Debug.Assert strArr.Count = 2
    Debug.Assert strArr.Item(0) = "( --aaaaaa"
    Debug.Assert strArr.Item(1) = "    x1"

End Sub